<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue router 笔记</title>
</head>

<body>
    <h2>所有组件都继承自 vue 的原型</h2>

    <h2>路由的发展</h2>
    <dl>
        <dt>后端路由阶段</dt>
        <dd>Jsp/PHP/Asp时期，后端处理url和页面之间的映射关系，然后由服务器端渲染好HTML代码，返回给客户端展示</dd>
        <dt>前后端分离阶段</dt>
        <dd>jQuery 时期，随着Ajax的出现，出现前后端分离的开发模式。这个时期采用大量由js,jq拼接生成的html代码</dd>
        <dt>前后路由阶段</dt>
        <dd>伴随SPA的出现，用户点击某个操作不在实现整个页面的重载，取而代之的是利用浏览器自身的特性(hash,history)，
            通过js动态刷新html，从而模拟多个视图的切换</dd>
        <dd>原理：一次从服务器端请求整套的state resource(html+css+js) ，然后点击链接切换视图时，从整套 state resource 里调用该视图的html+css+js</dd>
        <dd>技术：利用 url hash, 和 h5 history 对象</dd>
    </dl>

    <h2>hash</h2>
    <ul>
        <li>location.hash='home'</li>
    </ul>

    <h2>h5 history</h2>
    <ul>
        <li>history.pushState({},'','home')</li>
        <li>history.replaceState({},'','home')</li>
        <li>pushState replaceState 的区别，repalceState 改变的 url 没有保存历史状态，也就是无法 back() go()</li>
        <li>历史状态的 返回：history.back(),前进：history.go()</li>
        <li>history.go(num); --num:正负整数 </li>
        <li>history.back();</li>
        <li>history.back()=history.go(-1) </li>
        <li>history.forward=history.go(1) </li>
    </ul>

    <h2>vue router</h2>
    <ul>
        <li>在 vue router 的SPA 中，url的改变就是组件的切换</li>
    </ul>

    <dl>
        <dt>安装 vue router</dt>
        <dd>1,npm install vue-router --save</dd>
        <dd>2,Vue.use(VueRouter)</dd>
    </dl>

    <h2>vue router 的使用</h2>
    <ol>
        <li>创建映射到 url 的组件，也就是 vue 组件</li>
        <li>配置 url 到组件间的映射</li>
        <li>通过在视图中插入&lt;router-link> &lt;router-view> 使用路径映射关系(路由)</li>
        <li>视图使用 router-link 是一个vue-router 内部已经注册的组件，它在页面上最终会渲染成一个a标签</li>
        <li>router-view 相当&lt;cpn/>，它指示组件加载的区域</li>
    </ol>

    <h2>更改路由</h2>
    <ul>
        <li>视图使用 router-link</li>
        <li>js中使用 this.$router.push("/about") | this.$router.replace("/about") </li>
    </ul>

    <h2>路由绑定参数（拼接url）</h2>
    <ul>
        <li>routes:{path:/user/:uid}</li>
        <li>使用v-bind ：&lt;router-link :to="'/user/' + uid"> 绑定参数到 user 视图</li>
        <li>user组件拿到 user视图传递的参数：this.$route.params.uid</li>
    </ul>

    <h2>路由传参</h2>
    <dl>
        <dt>params 方式：</dt>
        <dd>路由配置：{path:/router/:uid}</dd>
        <dd>视图：&lt:router-link :to="'/router/' + uid"></dd>
        <dd>取参：$route.params.uid</dd>
        <dd>形成的链接：/router/123</dd>
        <dt>query 方式：</dt>
        <dd>路由配置：普通配置，不需要加动态值 :id</dd>
        <dd>视图：&lt;router-link :to="{path:'/router',query:{name:'leeneo',age:'28'}}">&lt;/router-link></dd>
        <dd>取参：$route.query | $route.query.name</dd>
        <dd>形成链接：/router?name=leeneo&age=28</dd>
        <dt>事件方式</dt>
        <dd>this.$router.push('/router'+this.uid)</dd>
        <dd>this.$router.push({path:'/router',query:{name:'neo',age:28}})</dd>
    </dl>


    <h2>路由的懒加载</h2>
    <ul>
        <li>懒加载：用到时方加载</li>
        <li>主要作用：将不同路由对应的组件分割成不同的js代码块，只有当路由被访问的时候，才加载对应代码</li>
    </ul>

    <h2>路由嵌套（分层）</h2>
    <ul>
        <li>&lt;router-link to="/home/news" tag="button">新闻&lt;/router-link></li>
        <li>在要追加层级的组件路由下添加 children --> routes:{Home:{children:[]}} </li>
    </ul>

    <h2>this.$router this.$route 的区别</h2>
    <ul>
        <li>this.$router:VueRouter 外层最大的VueRouter对象: this.$router.push()|replace()</li>
        <li>this.$route: 当前激活的路由(active of routes)对象，可以访问当前路由的 path,params,query等</li>
    </ul>

    <h2>全局守卫，勾子函数 router.beforeEach() and router.afterEach()</h2>
    <ul>
        <li>用于在进入页面之前做些限制，比如验证登录权限，比如设置页面title</li>
        <li>beforeEach(to,from,next) 需要 next 函数，否则运行会出错</li>
        <li>afterEach(to,from) 不需要 next 函数</li>
    </ul>

    <h2>使用 beforeEach() 设置页面title</h2>
    <dl>
        <dt>事件中设置title：</dt>
        <dd>created(){document.title = "首页-消息"}</dd>
        <dt>路由中设置title：</dt>
        <dd>1, route:{meta:{title:'简介' }}</dd>
        <dd>2, beforeEach((to, from, next) =>{document.title = to.matched[0].meta.title})</dd>
    </dl>

    <h2>其他守卫函数</h2>
    <ol>
        <dt>路由独享守卫</dt>
        <dd>route 里面配置 beforeEnter(to,from,next) 函数</dd>
        <dt>组件内守卫</dt>
        <dd>beforeRouteEnter(to,from,next), beforeRouteUpdate(to,from,next), beforeRouteLeave(to,from,next)</dd>
    </ol>

    <h2>keep-alive</h2>
    <ul>
        <li>keep-alive 是 Vue 内置的一个组件，可以使被包含的组件保留状态，或避免重新渲染</li>
        <li>router-view 如果被包在 keep-alive里面，所有路径匹配到的视图组件都会被缓存</li>
        <li>include: 字符串或正则表达式，只有匹配的组件才会被缓存</li>
        <li>exclude: 字符串或正则表达式，任何匹配的组件都不会被缓存</li>
        <li>使用：
            &lt;keep-alive exclude="User,Profile">
            &lt;router-view />
            &lt;/keep-alive>
        </li>
        <li>组件内使用 activated 或者 deactivated 函数，只有当使用了keep-alive时，这两个函数才会生效</li>
        <li>同时使用 beforeRouteLeave 函数，控制路由以保存状态并正确访问</li>
    </ul>

</body>

</html>